package io.renren.modules.aic.service.impl;

import io.renren.common.utils.ConfigConstant;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.DecimalUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.Query;
import io.renren.modules.aic.dao.CtocTransCountDao;
import io.renren.modules.aic.entity.CtocOrderEntity;
import io.renren.modules.aic.entity.CtocTransCountEntity;
import io.renren.modules.aic.entity.CtocTransactionEntity;
import io.renren.modules.aic.entity.MemberEntity;
import io.renren.modules.aic.entity.MemberMachineEntity;
import io.renren.modules.aic.service.CtocOrderService;
import io.renren.modules.aic.service.CtocTransCountService;
import io.renren.modules.aic.service.CtocTransactionService;
import io.renren.modules.aic.service.MemberMachineService;
import io.renren.modules.aic.service.MemberService;
import io.renren.modules.aic.service.TokenService;
import io.renren.modules.sys.service.SysConfigService;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

@Service("ctocTransCountService")
public class CtocTransCountServiceImpl extends ServiceImpl<CtocTransCountDao, CtocTransCountEntity> implements CtocTransCountService {

	@Autowired
	SysConfigService sysConfigService;

	@Autowired
	CtocOrderService ctocOrderService;

	@Autowired
	CtocTransactionService ctocTransactionService;

	@Autowired
	CtocTransCountDao ctocTransCountDao;

	@Autowired
	MemberService memberService;

	@Autowired
	MemberMachineService memberMachineService;

	@Autowired
	TokenService tokenService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String mobile = (String) params.get("mobile");
		Long memberId = null;
		if (StringUtils.isNotBlank(mobile)) {
			MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().setSqlSelect("id").eq("mobile", mobile));
			if (member == null) {
				memberId = Long.MAX_VALUE;
			} else {
				memberId = member.getId();
			}
		}
		Page<CtocTransCountEntity> page = this.selectPage(new Query<CtocTransCountEntity>(params).getPage(),
				new EntityWrapper<CtocTransCountEntity>().eq(memberId != null, "id", memberId));

		return new PageUtils(page);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void ctocTransCount() {

		Date now = new Date();

		// 买家30分钟未付款
		List<CtocTransactionEntity> transList = ctocTransactionService.selectList(new EntityWrapper<CtocTransactionEntity>()
				.setSqlSelect("id", "order_no", "buyer_member_id", "seller_member_id", "trans_fee", "coin_quantity").eq("status", ProjectConstant.CTOC_TRANS_STATUS_NEEDPAY)
				.lt("create_time", DateUtils.addDateMinutes(now, 0 - sysConfigService.getValueI(ConfigConstant.BUYER_PAYMENT_TIMEOUT))));
		if (CollectionUtils.isNotEmpty(transList)) {
			for (CtocTransactionEntity ctocTransaction : transList) {
				// 取消交易单
				ctocTransaction.setStatus(ProjectConstant.CTOC_TRANS_STATUS_CANCEL);
				ctocTransaction.setFinishTime(now);
				ctocTransaction.setUpdateTime(now);
				ctocTransactionService.updateById(ctocTransaction);

				// 设置挂单为取消
				CtocOrderEntity ctocOrder = ctocOrderService.selectOne(new EntityWrapper<CtocOrderEntity>().setSqlSelect("id").eq("order_no", ctocTransaction.getOrderNo()));
				ctocOrder.setStatus(ProjectConstant.CTOC_ORDER_STATUS_CANCEL);
				ctocOrder.setOrderDescription("付款超时取消");
				ctocOrder.setUpdateTime(now);
				ctocOrderService.updateById(ctocOrder);

				// 解冻卖家货币
				MemberEntity member = memberService.selectById(ctocTransaction.getSellerMemberId());
				double blocked = DecimalUtils.add(ctocTransaction.getCoinQuantity(), ctocTransaction.getTransFee());// 解冻金额=总币+手续费
				member.setBalance(DecimalUtils.add(blocked, member.getBalance()));// 余额+解冻金额
				member.setBlockedBalance(DecimalUtils.sub(member.getBlockedBalance(), blocked));// 冻结金额-解冻金额
				member.setUpdateTime(now);
				memberService.updateById(member);

				// 统计买家超时付款次数
				CtocTransCountEntity ctocTransCount = this.selectOne(new EntityWrapper<CtocTransCountEntity>().eq("member_id", ctocTransaction.getBuyerMemberId()).ge(
						"create_time", DateUtils.getStartOfDay(now)));
				if (ctocTransCount == null) {
					ctocTransCount = new CtocTransCountEntity();
					ctocTransCount.setMemberId(ctocTransaction.getBuyerMemberId());
					ctocTransCount.setPaymentTimeout(1);// 付款超时1次
					ctocTransCount.setCreateTime(now);
					this.insert(ctocTransCount);
				} else {
					ctocTransCount.setPaymentTimeout(ctocTransCount.getPaymentTimeout() + 1);// 超时取消增加一次
					ctocTransCount.setUpdateTime(now);
					this.updateById(ctocTransCount);
				}

				// 系统自动取消达3次 冻结账号7天 矿机停止收益
				if (ctocTransCount.getPaymentTimeout() >= sysConfigService.getValueI(ConfigConstant.WARNING_TIMES)) {

					// 账号冻结
					member = new MemberEntity();
					member.setId(ctocTransaction.getBuyerMemberId());
					member.setStatus(ProjectConstant.COMMON_STATUS_BLOCKED);
					member.setBlockedTime(DateUtils.addDateDays(now, sysConfigService.getValueI(ConfigConstant.BLOCKED_ACCOUNT_DAYS)));// 设置解冻时间
					member.setUpdateTime(now);
					memberService.updateById(member);

					// 矿机暂停收益
					MemberMachineEntity memberMachine = new MemberMachineEntity();
					memberMachine.setStatus(ProjectConstant.MACHINE_RUNSTATUS_PAUSE);
					memberMachine.setUpdateTime(now);
					memberMachineService.update(memberMachine,
							new EntityWrapper<MemberMachineEntity>().eq("status", ProjectConstant.MACHINE_RUNSTATUS_RUNNING).eq("member_id", ctocTransaction.getBuyerMemberId()));

					// 取消未成交的挂单
					ctocOrder = new CtocOrderEntity();
					ctocOrder.setStatus(ProjectConstant.CTOC_ORDER_STATUS_CANCEL);
					ctocOrder.setOrderDescription("付款超时次数达到上限取消");
					ctocOrder.setUpdateTime(now);
					ctocOrderService.update(ctocOrder,
							new EntityWrapper<CtocOrderEntity>().eq("status", ProjectConstant.CTOC_ORDER_STATUS_SUBMIT).eq("member_id", ctocTransaction.getBuyerMemberId()));
				}
			}
		}

		// 卖家6小时未确认
		transList = ctocTransactionService.selectList(new EntityWrapper<CtocTransactionEntity>().setSqlSelect("id", "seller_member_id")
				.eq("status", ProjectConstant.CTOC_TRANS_STATUS_PAID).eq("flag", ProjectConstant.COMMON_NO)
				.lt("payment_time", DateUtils.addDateHours(now, 0 - sysConfigService.getValueI(ConfigConstant.SELLER_CONFIRM_TIMEOUT))));
		if (CollectionUtils.isNotEmpty(transList)) {
			for (CtocTransactionEntity ctocTransaction : transList) {

				// 设置订单标记
				ctocTransaction.setFlag(ProjectConstant.COMMON_YES);
				ctocTransaction.setUpdateTime(now);
				ctocTransactionService.updateById(ctocTransaction);

				// 统计卖家超时确认
				CtocTransCountEntity ctocTransCount = this.selectOne(new EntityWrapper<CtocTransCountEntity>().eq("member_id", ctocTransaction.getSellerMemberId()).ge(
						"create_time", DateUtils.getStartOfDay(now)));
				if (ctocTransCount == null) {
					ctocTransCount = new CtocTransCountEntity();
					ctocTransCount.setMemberId(ctocTransaction.getSellerMemberId());
					ctocTransCount.setOrderUnconfirmed(1);
					ctocTransCount.setCreateTime(now);
					this.insert(ctocTransCount);
				} else {
					ctocTransCount.setOrderUnconfirmed(ctocTransCount.getOrderUnconfirmed() + 1);// 超时确认增加一次
					ctocTransCount.setUpdateTime(now);
					this.updateById(ctocTransCount);
				}

				// 卖家超时确认累计3次系统自动封号
				if (ctocTransCountDao.sumOrderUnconfirmed(ctocTransaction.getSellerMemberId()) >= sysConfigService.getValueI(ConfigConstant.FAIL_TIMES)) {
					MemberEntity member = new MemberEntity();
					member.setId(ctocTransaction.getSellerMemberId());
					member.setStatus(ProjectConstant.COMMON_STATUS_DISABLE);
					member.setUpdateTime(now);
					memberService.updateById(member);

					// 移动端登录会话过期
					tokenService.expireToken(member.getId());
				}
			}
		}
	}
}
